home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 4 / Amiga Tools 4.iso / grafix / raytracing / raylab / source / getworld.c < prev    next >
C/C++ Source or Header  |  1996-01-04  |  43KB  |  1,478 lines

  1. /* 
  2.     name: getworld.c
  3.  
  4.     Input handler
  5.     -------------
  6.     
  7.     This part will read and interpret a scene description file.
  8.  
  9.  
  10.  */
  11.  
  12.  
  13. #include  <stdio.h>
  14. #include  <stdlib.h>
  15. #include  <string.h>
  16.  
  17. #include  "defs.h"
  18. #include  "getworld.h"
  19. #include  "extern.h"
  20.  
  21.  
  22.     TEXTURE        DefaultTexture;
  23.     TRANSFORM    DefaultTransform;
  24.  
  25.  
  26. /*****************************************************************
  27.  *
  28.  *      This is the main imput routine
  29.  *
  30.  *****************************************************************/
  31.  
  32.  
  33. int CreateWorld(char *filename )
  34. {
  35.     int    RetOK=0,EndReached=-1;
  36.     char    strtmp[100];
  37.     FILE    *parfile;
  38.  
  39.     NumObjects=NumLights=0;
  40.     SetupDefaults();
  41.  
  42.     if((parfile=fopen(filename,"r"))!=0) {
  43.         fprintf(stderr,"\nBuilding scene\n[");
  44.         while((EndReached!=0)&&(RetOK==0)&&(getnextkeyword(parfile,strtmp)==0)) {
  45.         if(strcmp(strtmp,(char *)"PLANE:")==0)
  46.             RetOK=InitNewPlane(parfile);
  47.         else if(strcmp(strtmp,(char *)"SPHERE:")==0)
  48.             RetOK=InitNewSphere(parfile);
  49.         else if(strcmp(strtmp,(char *)"ELLIPSOID:")==0)
  50.             RetOK=InitNewEllipsoid(parfile);
  51.         else if(strcmp(strtmp,(char *)"TRIANGLE:")==0)
  52.             RetOK=InitNewTriangle(parfile);
  53.         else if(strcmp(strtmp,(char *)"BOX:")==0)
  54.             RetOK=InitNewBox(parfile);
  55.         else if(strcmp(strtmp,(char *)"DISC:")==0)
  56.             RetOK=InitNewDisc(parfile);
  57.         else if(strcmp(strtmp,(char *)"CYLINDER:")==0)
  58.             RetOK=InitNewCylinder(parfile);
  59.         else if(strcmp(strtmp,(char *)"LIGHT:")==0)
  60.             RetOK=InitNewLight(parfile);
  61.         else if(strcmp(strtmp,(char *)"CAMERA:")==0)
  62.             RetOK=InitCamera(parfile);
  63.         else if(strcmp(strtmp,(char *)"GLOBALS:")==0)
  64.             RetOK=InitGlobals(parfile);
  65.         else if(strcmp(strtmp,(char *)"DEFTEXTURE:")==0)
  66.             RetOK=InitTexture(&DefaultTexture,parfile);
  67.         else if(strcmp(strtmp,(char *)"DEFTRANSFORM:")==0)
  68.             RetOK=InitTransform(&DefaultTransform,parfile);
  69.         else if(strcmp(strtmp,(char *)"END")==0) {
  70.             EndReached=0;
  71.         }
  72.         else {
  73.             fprintf(stderr,"\n\nError: Unknown keyword \"%s\"",strtmp);
  74.             RetOK=-1;
  75.         }
  76.         }
  77.         fprintf(stderr,"]\n\n");
  78.         if(NumObjects<=0) {
  79.             fprintf(stderr,"No objects were declared!\n");
  80.             RetOK=-1;
  81.         }
  82.         if(NumLights<=0) {
  83.             fprintf(stderr,"No lights were declared!\n");
  84.             RetOK=-1;
  85.         }
  86.         if(RetOK!=0) fprintf(stderr,"*** Failed!\n\n");
  87.         fclose(parfile);
  88.     }
  89.     else {
  90.         RetOK=-1;
  91.         fprintf(stderr,"\n*** Could not open description file!\n");
  92.     }
  93.     return(RetOK);
  94. }
  95.  
  96.  
  97.  
  98. /*****************************************************************
  99.  *
  100.  *      Initialization routines
  101.  *
  102.  *****************************************************************/
  103.  
  104.  
  105. int InitNewPlane(FILE *parfile)
  106. {
  107.     double    dtmp;
  108.     char    strtmp[100];
  109.     PLANE    TmpPlane, *NewPlane;
  110.     OBJECT    *NewObject;
  111.     TEXTURE    TmpText;
  112.     TRANSFORM TmpTransform;
  113.     int    RetOK=0,EndReached=-1;
  114.  
  115.     fprintf(stderr,".");
  116.  
  117.     if(NumObjects>=maxobjects) {
  118.         fprintf(stderr,"\n*** Maximum amount of objects exceeded!\n");
  119.         RetOK=-1;
  120.     }
  121.  
  122.     else {
  123.       CopyTexture(&TmpText,&DefaultTexture);
  124.       CopyTransform(&TmpTransform,&DefaultTransform);
  125.  
  126.       TmpPlane.Normal.x=0.0;    /* Set default values */
  127.       TmpPlane.Normal.y=0.0;
  128.       TmpPlane.Normal.z=1.0;
  129.       TmpPlane.a=0.0;
  130.  
  131.       if(getnextkeyword(parfile,strtmp)==0) {        /* Get first keyword */
  132.         while((EndReached!=0)&&(RetOK==0)) {
  133.         if(strcmp(strtmp,(char *)"NORMAL")==0) {
  134.                 if(getnextnumber(parfile,&dtmp)==0)
  135.                 set_dvalue(&TmpPlane.Normal.x,dtmp,mincoord,maxcoord,strtmp);
  136.                 if(getnextnumber(parfile,&dtmp)==0)
  137.                 set_dvalue(&TmpPlane.Normal.y,dtmp,mincoord,maxcoord,strtmp);
  138.                 if(getnextnumber(parfile,&dtmp)==0)
  139.                 set_dvalue(&TmpPlane.Normal.z,dtmp,mincoord,maxcoord,strtmp);
  140.                 else EndReached=0;
  141.         }
  142.         else if(strcmp(strtmp,(char *)"OFFSET")==0) {
  143.                 if(getnextnumber(parfile,&dtmp)==0)
  144.                     set_dvalue(&TmpPlane.a,dtmp,mincoord,maxcoord,strtmp);
  145.                 else EndReached=0;
  146.         }
  147.         else if(strcmp(strtmp,(char *)"TEXTURE:")==0) {
  148.             RetOK=InitTexture(&TmpText,parfile);
  149.         }
  150.         else if(strcmp(strtmp,(char *)"TRANSFORM:")==0) {
  151.             RetOK=InitTransform(&TmpTransform,parfile);
  152.             AddTransform(&TmpText.Transform,&TmpTransform);
  153.         }
  154.         else if(strcmp(strtmp,(char *)":END")==0) {
  155.             EndReached=0;
  156.         }
  157.         else {
  158.             fprintf(stderr,"\nError: Unknown plane-keyword \"%s\"\n",strtmp);
  159.             RetOK=-1;
  160.         }
  161.         if((RetOK==0)&&(EndReached!=0)) {
  162.             if(getnextkeyword(parfile,strtmp)!=0) RetOK=-1;        /* Get next keyword */
  163.         }
  164.         }
  165.       }
  166.  
  167.       if(RetOK==0) {
  168.         if((NewObject=(OBJECT *)malloc(sizeof(OBJECT)))!=NULL) {
  169.         if((NewPlane=(PLANE *)malloc(sizeof(PLANE)))!=NULL) {
  170.             CopyVector(&NewPlane->Normal,&TmpPlane.Normal);
  171.             NewPlane->a=TmpPlane.a;
  172.  
  173.             NewObject->ShapeType=SHAPE_PLANE;
  174.             NewObject->Shape=NewPlane;
  175.             CopyTexture(&NewObject->Texture,&TmpText);
  176.             CopyTransform(&NewObject->Transform,&TmpTransform);
  177.  
  178.             ObjectArray[NumObjects]=NewObject;
  179.             NumObjects++;
  180.         }
  181.         else {
  182.             fprintf(stderr,"\nError: Could not allocate memory for new plane\n");
  183.             free(NewObject);
  184.             RetOK=-1;
  185.         }
  186.         }
  187.         else {
  188.         fprintf(stderr,"\nError: Could not allocate memory for new object\n");
  189.         RetOK=-1;
  190.         }
  191.       }
  192.     }
  193.     return(RetOK);
  194. }
  195.  
  196.  
  197. int InitNewSphere(FILE *parfile)
  198. {
  199.     double    dtmp;
  200.     char    strtmp[100];
  201.     SPHERE    TmpSphere, *NewSphere;
  202.     OBJECT    *NewObject;
  203.     TEXTURE    TmpText;
  204.     TRANSFORM TmpTransform;
  205.     int    RetOK=0,EndReached=-1;
  206.  
  207.     fprintf(stderr,".");
  208.  
  209.     if(NumObjects>=maxobjects) {
  210.         fprintf(stderr,"\n*** Maximum amount of objects exceeded!\n");
  211.         RetOK=-1;
  212.     }
  213.  
  214.     else {
  215.       CopyTexture(&TmpText,&DefaultTexture);
  216.       CopyTransform(&TmpTransform,&DefaultTransform);
  217.  
  218.       TmpSphere.Centre.x=0.0;    /* Set default values */
  219.       TmpSphere.Centre.y=0.0;
  220.       TmpSphere.Centre.z=0.0;
  221.       TmpSphere.r=1.0;
  222.  
  223.       if(getnextkeyword(parfile,strtmp)==0) {        /* Get first keyword */
  224.         while((EndReached!=0)&&(RetOK==0)) {
  225.         if(strcmp(strtmp,(char *)"CENTRE")==0) {
  226.                 if(getnextnumber(parfile,&dtmp)==0)
  227.                 set_dvalue(&TmpSphere.Centre.x,dtmp,mincoord,maxcoord,strtmp);
  228.                 if(getnextnumber(parfile,&dtmp)==0)
  229.                 set_dvalue(&TmpSphere.Centre.y,dtmp,mincoord,maxcoord,strtmp);
  230.                 if(getnextnumber(parfile,&dtmp)==0)
  231.                 set_dvalue(&TmpSphere.Centre.z,dtmp,mincoord,maxcoord,strtmp);
  232.                 else EndReached=0;
  233.         }
  234.         else if(strcmp(strtmp,(char *)"RADIUS")==0) {
  235.                 if(getnextnumber(parfile,&dtmp)==0)
  236.                     set_dvalue(&TmpSphere.r,dtmp,mincoord,maxcoord,strtmp);
  237.                 else EndReached=0;
  238.         }
  239.         else if(strcmp(strtmp,(char *)"TEXTURE:")==0) {
  240.             RetOK=InitTexture(&TmpText,parfile);
  241.         }
  242.         else if(strcmp(strtmp,(char *)"TRANSFORM:")==0) {
  243.             RetOK=InitTransform(&TmpTransform,parfile);
  244.             AddTransform(&TmpText.Transform,&TmpTransform);
  245.         }
  246.         else if(strcmp(strtmp,(char *)":END")==0) {
  247.             EndReached=0;
  248.         }
  249.         else {
  250.             fprintf(stderr,"\nError: Unknown sphere-keyword \"%s\"\n",strtmp);
  251.             RetOK=-1;
  252.         }
  253.         if((RetOK==0)&&(EndReached!=0)) {
  254.             if(getnextkeyword(parfile,strtmp)!=0) RetOK=-1;        /* Get next keyword */
  255.         }
  256.         }
  257.       }
  258.  
  259.       if(RetOK==0) {
  260.         if((NewObject=(OBJECT *)malloc(sizeof(OBJECT)))!=NULL) {
  261.         if((NewSphere=(SPHERE *)malloc(sizeof(SPHERE)))!=NULL) {
  262.             CopyPoint(&NewSphere->Centre,&TmpSphere.Centre);
  263.             NewSphere->r=TmpSphere.r;
  264.  
  265.             NewObject->ShapeType=SHAPE_SPHERE;
  266.             NewObject->Shape=NewSphere;
  267.             CopyTexture(&NewObject->Texture,&TmpText);
  268.             CopyTransform(&NewObject->Transform,&TmpTransform);
  269.  
  270.             ObjectArray[NumObjects]=NewObject;
  271.             NumObjects++;
  272.         }
  273.         else {
  274.             fprintf(stderr,"\nError: Could not allocate memory for new sphere\n");
  275.             free(NewObject);
  276.             RetOK=-1;
  277.         }
  278.         }
  279.         else {
  280.         fprintf(stderr,"\nError: Could not allocate memory for new object\n");
  281.         RetOK=-1;
  282.         }
  283.       }
  284.     }
  285.     return(RetOK);
  286. }
  287.  
  288.  
  289.  
  290. int InitNewEllipsoid(FILE *parfile)
  291. {
  292.     double    dtmp;
  293.     char    strtmp[100];
  294.     ELLIPSOID    TmpEllipsoid, *NewEllipsoid;
  295.     OBJECT    *NewObject;
  296.     TEXTURE    TmpText;
  297.     TRANSFORM TmpTransform;
  298.     int    RetOK=0,EndReached=-1;
  299.  
  300.     fprintf(stderr,".");
  301.  
  302.     if(NumObjects>=maxobjects) {
  303.         fprintf(stderr,"\n*** Maximum amount of objects exceeded!\n");
  304.         RetOK=-1;
  305.     }
  306.  
  307.     else {
  308.       CopyTexture(&TmpText,&DefaultTexture);
  309.       CopyTransform(&TmpTransform,&DefaultTransform);
  310.  
  311.       TmpEllipsoid.Centre.x=0.0;    /* Set default values */
  312.       TmpEllipsoid.Centre.y=0.0;
  313.       TmpEllipsoid.Centre.z=0.0;
  314.       TmpEllipsoid.Radius.x=1.0;
  315.       TmpEllipsoid.Radius.y=1.0;
  316.       TmpEllipsoid.Radius.z=1.0;
  317.  
  318.       if(getnextkeyword(parfile,strtmp)==0) {        /* Get first keyword */
  319.         while((EndReached!=0)&&(RetOK==0)) {
  320.         if(strcmp(strtmp,(char *)"CENTRE")==0) {
  321.                 if(getnextnumber(parfile,&dtmp)==0)
  322.                 set_dvalue(&TmpEllipsoid.Centre.x,dtmp,mincoord,maxcoord,strtmp);
  323.                 if(getnextnumber(parfile,&dtmp)==0)
  324.                 set_dvalue(&TmpEllipsoid.Centre.y,dtmp,mincoord,maxcoord,strtmp);
  325.                 if(getnextnumber(parfile,&dtmp)==0)
  326.                 set_dvalue(&TmpEllipsoid.Centre.z,dtmp,mincoord,maxcoord,strtmp);
  327.                 else EndReached=0;
  328.         }
  329.         else if(strcmp(strtmp,(char *)"RADIUS")==0) {
  330.                 if(getnextnumber(parfile,&dtmp)==0)
  331.                     set_dvalue(&TmpEllipsoid.Radius.x,dtmp,mincoord,maxcoord,strtmp);
  332.                 if(getnextnumber(parfile,&dtmp)==0)
  333.                 set_dvalue(&TmpEllipsoid.Radius.y,dtmp,mincoord,maxcoord,strtmp);
  334.             if(getnextnumber(parfile,&dtmp)==0)
  335.                 set_dvalue(&TmpEllipsoid.Radius.z,dtmp,mincoord,maxcoord,strtmp);
  336.                 else EndReached=0;
  337.         }
  338.         else if(strcmp(strtmp,(char *)"TEXTURE:")==0) {
  339.             RetOK=InitTexture(&TmpText,parfile);
  340.         }
  341.         else if(strcmp(strtmp,(char *)"TRANSFORM:")==0) {
  342.             RetOK=InitTransform(&TmpTransform,parfile);
  343.             AddTransform(&TmpText.Transform,&TmpTransform);
  344.         }
  345.         else if(strcmp(strtmp,(char *)":END")==0) {
  346.             EndReached=0;
  347.         }
  348.         else {
  349.             fprintf(stderr,"\nError: Unknown ellipsoid-keyword \"%s\"\n",strtmp);
  350.             RetOK=-1;
  351.         }
  352.         if((RetOK==0)&&(EndReached!=0)) {
  353.             if(getnextkeyword(parfile,strtmp)!=0) RetOK=-1;        /* Get next keyword */
  354.         }
  355.         }
  356.       }
  357.  
  358.       if(RetOK==0) {
  359.         if((NewObject=(OBJECT *)malloc(sizeof(OBJECT)))!=NULL) {
  360.         if((NewEllipsoid=(ELLIPSOID *)malloc(sizeof(ELLIPSOID)))!=NULL) {
  361.             CopyPoint(&NewEllipsoid->Centre,&TmpEllipsoid.Centre);
  362.             CopyVector(&NewEllipsoid->Radius,&TmpEllipsoid.Radius);
  363.  
  364.             NewObject->ShapeType=SHAPE_ELLIPSOID;
  365.             NewObject->Shape=NewEllipsoid;
  366.             CopyTexture(&NewObject->Texture,&TmpText);
  367.             CopyTransform(&NewObject->Transform,&TmpTransform);
  368.  
  369.             ObjectArray[NumObjects]=NewObject;
  370.             NumObjects++;
  371.         }
  372.         else {
  373.             fprintf(stderr,"\nError: Could not allocate memory for new ellipsoid\n");
  374.             free(NewObject);
  375.             RetOK=-1;
  376.         }
  377.         }
  378.         else {
  379.         fprintf(stderr,"\nError: Could not allocate memory for new object\n");
  380.         RetOK=-1;
  381.         }
  382.       }
  383.     }
  384.     return(RetOK);
  385. }
  386.  
  387.  
  388.  
  389. int InitNewTriangle(FILE *parfile)
  390. {
  391.     double    dtmp,maxx,maxy,maxz,minx,miny,minz;
  392.     char    strtmp[100];
  393.     TRIANGLE  *NewTriangle;
  394.     TRANSFORM TmpTransform;
  395.     POINT    Corners[3];
  396.     OBJECT    *NewObject;
  397.     TEXTURE    TmpText;
  398.     VECTOR    v1,v2,n;
  399.     int    RetOK=0,EndReached=-1,i;
  400.  
  401.     fprintf(stderr,".");
  402.  
  403.     if(NumObjects>=maxobjects) {
  404.         fprintf(stderr,"\n*** Maximum amount of objects exceeded!\n");
  405.         RetOK=-1;
  406.     }
  407.  
  408.     else {
  409.       CopyTexture(&TmpText,&DefaultTexture);
  410.       CopyTransform(&TmpTransform,&DefaultTransform);
  411.  
  412.       Corners[0].x=0.0;            /* Set default values */
  413.       Corners[0].y=0.0;
  414.       Corners[0].z=0.0;
  415.       Corners[1].x=1.0;
  416.       Corners[1].y=1.0;
  417.       Corners[1].z=1.0;
  418.       Corners[2].x=-1.0;
  419.       Corners[2].y=1.0;
  420.       Corners[2].z=1.0;
  421.  
  422.       if(getnextkeyword(parfile,strtmp)==0) {        /* Get first keyword */
  423.         while((EndReached!=0)&&(RetOK==0)) {
  424.         if(strcmp(strtmp,(char *)"CORNERS")==0) {
  425.             i=0;
  426.             while((i<3)&&(EndReached!=0)) {
  427.                 if(getnextnumber(parfile,&dtmp)==0)
  428.                 set_dvalue(&Corners[i].x,dtmp,mincoord,maxcoord,strtmp);
  429.                 if(getnextnumber(parfile,&dtmp)==0)
  430.                 set_dvalue(&Corners[i].y,dtmp,mincoord,maxcoord,strtmp);
  431.                 if(getnextnumber(parfile,&dtmp)==0)
  432.                 set_dvalue(&Corners[i].z,dtmp,mincoord,maxcoord,strtmp);
  433.                 else EndReached=0;
  434.             i++;
  435.             }
  436.         }
  437.         else if(strcmp(strtmp,(char *)"TEXTURE:")==0) {
  438.             RetOK=InitTexture(&TmpText,parfile);
  439.         }
  440.         else if(strcmp(strtmp,(char *)"TRANSFORM:")==0) {
  441.             RetOK=InitTransform(&TmpTransform,parfile);
  442.             AddTransform(&TmpText.Transform,&TmpTransform);
  443.         }
  444.         else if(strcmp(strtmp,(char *)":END")==0) {
  445.             EndReached=0;
  446.         }
  447.         else {
  448.             fprintf(stderr,"\nError: Unknown triangle-keyword \"%s\"\n",strtmp);
  449.             RetOK=-1;
  450.         }
  451.         if((RetOK==0)&&(EndReached!=0)) {
  452.             if(getnextkeyword(parfile,strtmp)!=0) RetOK=-1;        /* Get next keyword */
  453.         }
  454.         }
  455.       }
  456.  
  457.       if(RetOK==0) {
  458.         if((NewObject=(OBJECT *)malloc(sizeof(OBJECT)))!=NULL) {
  459.         if((NewTriangle=(TRIANGLE *)malloc(sizeof(TRIANGLE)))!=NULL) {
  460.             for(i=0;i<3;i++) {
  461.                 CopyPoint(&NewTriangle->Corners[i],&Corners[i]);
  462.             }
  463.             v1.x=Corners[1].x-Corners[0].x;
  464.             v1.y=Corners[1].y-Corners[0].y;
  465.             v1.z=Corners[1].z-Corners[0].z;
  466.             v2.x=Corners[2].x-Corners[0].x;
  467.             v2.y=Corners[2].y-Corners[0].y;
  468.             v2.z=Corners[2].z-Corners[0].z;
  469.             CrossProduct(&n,&v1,&v2);
  470.             CopyVector(&NewTriangle->Plane.Normal,&n);
  471.             NewTriangle->Plane.a=Corners[0].x*n.x+Corners[0].y*n.y+Corners[0].z*n.z;
  472.  
  473.             minx=maxx=Corners[0].x;                /* Calculate min/max boundaries for x,y,z... */
  474.             miny=maxy=Corners[0].y;                /* This significantly speeds up the checking */
  475.             minz=maxz=Corners[0].z;                /* for ray-intersections.                    */
  476.             if(Corners[1].x>maxx) maxx=Corners[1].x;
  477.             else if(Corners[1].x<minx) minx=Corners[1].x;
  478.             if(Corners[2].x>maxx) maxx=Corners[2].x;
  479.             else if(Corners[2].x<minx) minx=Corners[2].x;
  480.             if(Corners[1].y>maxy) maxy=Corners[1].y;
  481.             else if(Corners[1].y<miny) miny=Corners[1].y;
  482.             if(Corners[2].y>maxy) maxy=Corners[2].y;
  483.             else if(Corners[2].y<miny) miny=Corners[2].y;
  484.             if(Corners[1].z>maxz) maxz=Corners[1].z;
  485.             else if(Corners[1].z<minz) minz=Corners[1].z;
  486.             if(Corners[2].z>maxz) maxz=Corners[2].z;
  487.             else if(Corners[2].z<minz) minz=Corners[2].z;
  488.             NewTriangle->Min.x=minx; NewTriangle->Max.x=maxx;
  489.             NewTriangle->Min.y=miny; NewTriangle->Max.y=maxy;
  490.             NewTriangle->Min.z=minz; NewTriangle->Max.z=maxz;
  491.  
  492.             NewObject->ShapeType=SHAPE_TRIANGLE;
  493.             NewObject->Shape=NewTriangle;
  494.             CopyTexture(&NewObject->Texture,&TmpText);
  495.             CopyTransform(&NewObject->Transform,&TmpTransform);
  496.  
  497.             ObjectArray[NumObjects]=NewObject;
  498.             NumObjects++;
  499.         }
  500.         else {
  501.             fprintf(stderr,"\nError: Could not allocate memory for new triangle\n");
  502.             free(NewObject);
  503.             RetOK=-1;
  504.         }
  505.         }
  506.         else {
  507.         fprintf(stderr,"\nError: Could not allocate memory for new object\n");
  508.         RetOK=-1;
  509.         }
  510.       }
  511.     }
  512.     return(RetOK);
  513. }
  514.  
  515.  
  516.  
  517. int InitNewBox(FILE *parfile)
  518. {
  519.     double    dtmp,maxx,maxy,maxz,minx,miny,minz;
  520.     char    strtmp[100];
  521.     BOX    *NewBox;
  522.     POINT    Corners[2];
  523.     OBJECT    *NewObject;
  524.     TEXTURE    TmpText;
  525.     TRANSFORM TmpTransform;
  526.     int    RetOK=0,EndReached=-1,i;
  527.  
  528.     fprintf(stderr,".");
  529.  
  530.     if(NumObjects>=maxobjects) {
  531.         fprintf(stderr,"\n*** Maximum amount of objects exceeded!\n");
  532.         RetOK=-1;
  533.     }
  534.  
  535.     else {
  536.       CopyTexture(&TmpText,&DefaultTexture);
  537.       CopyTransform(&TmpTransform,&DefaultTransform);
  538.  
  539.       Corners[0].x=0.0;            /* Set default values */
  540.       Corners[0].y=0.0;
  541.       Corners[0].z=0.0;
  542.       Corners[1].x=1.0;
  543.       Corners[1].y=1.0;
  544.       Corners[1].z=1.0;
  545.  
  546.       if(getnextkeyword(parfile,strtmp)==0) {        /* Get first keyword */
  547.         while((EndReached!=0)&&(RetOK==0)) {
  548.         if(strcmp(strtmp,(char *)"CORNERS")==0) {
  549.             i=0;
  550.             while((i<2)&&(EndReached!=0)) {
  551.                 if(getnextnumber(parfile,&dtmp)==0)
  552.                 set_dvalue(&Corners[i].x,dtmp,mincoord,maxcoord,strtmp);
  553.                 if(getnextnumber(parfile,&dtmp)==0)
  554.                 set_dvalue(&Corners[i].y,dtmp,mincoord,maxcoord,strtmp);
  555.                 if(getnextnumber(parfile,&dtmp)==0)
  556.                 set_dvalue(&Corners[i].z,dtmp,mincoord,maxcoord,strtmp);
  557.                 else EndReached=0;
  558.             i++;
  559.             }
  560.         }
  561.         else if(strcmp(strtmp,(char *)"TEXTURE:")==0) {
  562.             RetOK=InitTexture(&TmpText,parfile);
  563.         }
  564.         else if(strcmp(strtmp,(char *)"TRANSFORM:")==0) {
  565.             RetOK=InitTransform(&TmpTransform,parfile);
  566.             AddTransform(&TmpText.Transform,&TmpTransform);
  567.         }
  568.         else if(strcmp(strtmp,(char *)":END")==0) {
  569.             EndReached=0;
  570.         }
  571.         else {
  572.             fprintf(stderr,"\nError: Unknown box-keyword \"%s\"\n",strtmp);
  573.             RetOK=-1;
  574.         }
  575.         if((RetOK==0)&&(EndReached!=0)) {
  576.             if(getnextkeyword(parfile,strtmp)!=0) RetOK=-1;        /* Get next keyword */
  577.         }
  578.         }
  579.       }
  580.  
  581.       if(RetOK==0) {
  582.         if((NewObject=(OBJECT *)malloc(sizeof(OBJECT)))!=NULL) {
  583.         if((NewBox=(BOX *)malloc(sizeof(BOX)))!=NULL) {
  584.             CreateVector(&NewBox->Planes[0].Normal,-1.0,0.0,0.0);
  585.             CreateVector(&NewBox->Planes[1].Normal,1.0,0.0,0.0);
  586.             CreateVector(&NewBox->Planes[2].Normal,0.0,-1.0,0.0);
  587.             CreateVector(&NewBox->Planes[3].Normal,0.0,1.0,0.0);
  588.             CreateVector(&NewBox->Planes[4].Normal,0.0,0.0,-1.0);
  589.             CreateVector(&NewBox->Planes[5].Normal,0.0,0.0,1.0);
  590.             
  591.             minx=maxx=Corners[0].x;                /* Calculate min/max boundaries for x,y,z...    */
  592.             miny=maxy=Corners[0].y;                /* This is so that you can give the coordinates */
  593.             minz=maxz=Corners[0].z;                /* in any order.                                */
  594.             if(Corners[1].x>maxx) maxx=Corners[1].x;
  595.             else if(Corners[1].x<minx) minx=Corners[1].x;
  596.             if(Corners[1].y>maxy) maxy=Corners[1].y;
  597.             else if(Corners[1].y<miny) miny=Corners[1].y;
  598.             if(Corners[1].z>maxz) maxz=Corners[1].z;
  599.             else if(Corners[1].z<minz) minz=Corners[1].z;
  600.  
  601.             NewBox->Planes[0].a=-minx;
  602.             NewBox->Planes[1].a=maxx;
  603.             NewBox->Planes[2].a=-miny;
  604.             NewBox->Planes[3].a=maxy;
  605.             NewBox->Planes[4].a=-minz;
  606.             NewBox->Planes[5].a=maxz;
  607.  
  608.             CreatePoint(&NewBox->Corners[0],minx,miny,minz);
  609.             CreatePoint(&NewBox->Corners[1],maxx,maxy,maxz);
  610.  
  611.             NewObject->ShapeType=SHAPE_BOX;
  612.             NewObject->Shape=NewBox;
  613.             CopyTexture(&NewObject->Texture,&TmpText);
  614.             CopyTransform(&NewObject->Transform,&TmpTransform);
  615.  
  616.             ObjectArray[NumObjects]=NewObject;
  617.             NumObjects++;
  618.         }
  619.         else {
  620.             fprintf(stderr,"\nError: Could not allocate memory for new box\n");
  621.             free(NewObject);
  622.             RetOK=-1;
  623.         }
  624.         }
  625.         else {
  626.         fprintf(stderr,"\nError: Could not allocate memory for new object\n");
  627.         RetOK=-1;
  628.         }
  629.       }
  630.     }
  631.     return(RetOK);
  632. }
  633.  
  634.  
  635. int InitNewDisc(FILE *parfile)
  636. {
  637.     double    dtmp;
  638.     char    strtmp[100];
  639.     DISC    TmpDisc, *NewDisc;
  640.     OBJECT    *NewObject;
  641.     TEXTURE    TmpText;
  642.     TRANSFORM TmpTransform;
  643.     int    RetOK=0,EndReached=-1;
  644.  
  645.     fprintf(stderr,".");
  646.  
  647.     if(NumObjects>=maxobjects) {
  648.         fprintf(stderr,"\n*** Maximum amount of objects exceeded!\n");
  649.         RetOK=-1;
  650.     }
  651.  
  652.     else {
  653.       CopyTexture(&TmpText,&DefaultTexture);
  654.       CopyTransform(&TmpTransform,&DefaultTransform);
  655.  
  656.       TmpDisc.Plane.Normal.x=0.0;    /* Set default values */
  657.       TmpDisc.Plane.Normal.y=0.0;
  658.       TmpDisc.Plane.Normal.z=1.0;
  659.       TmpDisc.Plane.a=0.0;
  660.       TmpDisc.r=1.0;
  661.  
  662.       if(getnextkeyword(parfile,strtmp)==0) {        /* Get first keyword */
  663.         while((EndReached!=0)&&(RetOK==0)) {
  664.         if(strcmp(strtmp,(char *)"NORMAL")==0) {
  665.                 if(getnextnumber(parfile,&dtmp)==0)
  666.                 set_dvalue(&TmpDisc.Plane.Normal.x,dtmp,mincoord,maxcoord,strtmp);
  667.                 if(getnextnumber(parfile,&dtmp)==0)
  668.                 set_dvalue(&TmpDisc.Plane.Normal.y,dtmp,mincoord,maxcoord,strtmp);
  669.                 if(getnextnumber(parfile,&dtmp)==0)
  670.                 set_dvalue(&TmpDisc.Plane.Normal.z,dtmp,mincoord,maxcoord,strtmp);
  671.                 else EndReached=0;
  672.         }
  673.         else if(strcmp(strtmp,(char *)"CENTRE")==0) {
  674.                 if(getnextnumber(parfile,&dtmp)==0)
  675.                 set_dvalue(&TmpDisc.Centre.x,dtmp,mincoord,maxcoord,strtmp);
  676.                 if(getnextnumber(parfile,&dtmp)==0)
  677.                 set_dvalue(&TmpDisc.Centre.y,dtmp,mincoord,maxcoord,strtmp);
  678.                 if(getnextnumber(parfile,&dtmp)==0)
  679.                 set_dvalue(&TmpDisc.Centre.z,dtmp,mincoord,maxcoord,strtmp);
  680.                 else EndReached=0;
  681.         }
  682.         else if(strcmp(strtmp,(char *)"RADIUS")==0) {
  683.                 if(getnextnumber(parfile,&dtmp)==0)
  684.                     set_dvalue(&TmpDisc.r,dtmp,mincoord,maxcoord,strtmp);
  685.                 else EndReached=0;
  686.         }
  687.         else if(strcmp(strtmp,(char *)"TEXTURE:")==0) {
  688.             RetOK=InitTexture(&TmpText,parfile);
  689.         }
  690.         else if(strcmp(strtmp,(char *)"TRANSFORM:")==0) {
  691.             RetOK=InitTransform(&TmpTransform,parfile);
  692.             AddTransform(&TmpText.Transform,&TmpTransform);
  693.         }
  694.         else if(strcmp(strtmp,(char *)":END")==0) {
  695.             EndReached=0;
  696.         }
  697.         else {
  698.             fprintf(stderr,"\nError: Unknown disc-keyword \"%s\"\n",strtmp);
  699.             RetOK=-1;
  700.         }
  701.         if((RetOK==0)&&(EndReached!=0)) {
  702.             if(getnextkeyword(parfile,strtmp)!=0) RetOK=-1;        /* Get next keyword */
  703.         }
  704.         }
  705.       }
  706.  
  707.       if(RetOK==0) {
  708.         if((NewObject=(OBJECT *)malloc(sizeof(OBJECT)))!=NULL) {
  709.         if((NewDisc=(DISC *)malloc(sizeof(DISC)))!=NULL) {
  710.             CopyPoint(&NewDisc->Centre,&TmpDisc.Centre);
  711.             NewDisc->r=TmpDisc.r;
  712.             CopyVector(&NewDisc->Plane.Normal,&TmpDisc.Plane.Normal);
  713.             NewDisc->Plane.a=(TmpDisc.Plane.Normal.x*TmpDisc.Centre.x+TmpDisc.Plane.Normal.y*TmpDisc.Centre.y+TmpDisc.Plane.Normal.z*TmpDisc.Centre.z);
  714.  
  715.             NewObject->ShapeType=SHAPE_DISC;
  716.             NewObject->Shape=NewDisc;
  717.             CopyTexture(&NewObject->Texture,&TmpText);
  718.             CopyTransform(&NewObject->Transform,&TmpTransform);
  719.  
  720.             ObjectArray[NumObjects]=NewObject;
  721.             NumObjects++;
  722.         }
  723.         else {
  724.             fprintf(stderr,"\nError: Could not allocate memory for new disc\n");
  725.             free(NewObject);
  726.             RetOK=-1;
  727.         }
  728.         }
  729.         else {
  730.         fprintf(stderr,"\nError: Could not allocate memory for new object\n");
  731.         RetOK=-1;
  732.         }
  733.       }
  734.     }
  735.     return(RetOK);
  736. }
  737.  
  738.  
  739.  
  740. int InitNewCylinder(FILE *parfile)
  741. {
  742.     double    dtmp,nx,ny,nz;
  743.     char    strtmp[100];
  744.     CYLINDER    TmpCyl, *NewCyl;
  745.     OBJECT    *NewObject;
  746.     TEXTURE    TmpText;
  747.     TRANSFORM TmpTransform;
  748.     int    RetOK=0,EndReached=-1;
  749.  
  750.     fprintf(stderr,".");
  751.  
  752.     if(NumObjects>=maxobjects) {
  753.         fprintf(stderr,"\n*** Maximum amount of objects exceeded!\n");
  754.         RetOK=-1;
  755.     }
  756.  
  757.     else {
  758.       CopyTexture(&TmpText,&DefaultTexture);
  759.       CopyTransform(&TmpTransform,&DefaultTransform);
  760.  
  761.       CreatePoint(&TmpCyl.Ends[0],0.0,0.0,0.0);
  762.       CreatePoint(&TmpCyl.Ends[1],0.0,0.0,1.0);
  763.       TmpCyl.r=1.0;
  764.  
  765.       if(getnextkeyword(parfile,strtmp)==0) {        /* Get first keyword */
  766.         while((EndReached!=0)&&(RetOK==0)) {
  767.         if(strcmp(strtmp,(char *)"HEIGHT")==0) {
  768.                 if(getnextnumber(parfile,&dtmp)==0) {
  769.                 set_dvalue(&TmpCyl.Ends[1].z,dtmp,mincoord,maxcoord,strtmp);
  770.                 TmpCyl.Ends[0].x=TmpCyl.Ends[0].y=TmpCyl.Ends[0].z=TmpCyl.Ends[1].x=TmpCyl.Ends[1].y=0.0;
  771.             }
  772.                 else EndReached=0;
  773.         }
  774.         else if(strcmp(strtmp,(char *)"START")==0) {
  775.                 if(getnextnumber(parfile,&dtmp)==0)
  776.                 set_dvalue(&TmpCyl.Ends[0].x,dtmp,mincoord,maxcoord,strtmp);
  777.                 if(getnextnumber(parfile,&dtmp)==0)
  778.                 set_dvalue(&TmpCyl.Ends[0].y,dtmp,mincoord,maxcoord,strtmp);
  779.                 if(getnextnumber(parfile,&dtmp)==0)
  780.                 set_dvalue(&TmpCyl.Ends[0].z,dtmp,mincoord,maxcoord,strtmp);
  781.                 else EndReached=0;
  782.         }
  783.         else if(strcmp(strtmp,(char *)"END")==0) {
  784.                 if(getnextnumber(parfile,&dtmp)==0)
  785.                 set_dvalue(&TmpCyl.Ends[1].x,dtmp,mincoord,maxcoord,strtmp);
  786.                 if(getnextnumber(parfile,&dtmp)==0)
  787.                 set_dvalue(&TmpCyl.Ends[1].y,dtmp,mincoord,maxcoord,strtmp);
  788.                 if(getnextnumber(parfile,&dtmp)==0)
  789.                 set_dvalue(&TmpCyl.Ends[1].z,dtmp,mincoord,maxcoord,strtmp);
  790.                 else EndReached=0;
  791.         }
  792.         else if(strcmp(strtmp,(char *)"RADIUS")==0) {
  793.                 if(getnextnumber(parfile,&dtmp)==0)
  794.                     set_dvalue(&TmpCyl.r,dtmp,mincoord,maxcoord,strtmp);
  795.                 else EndReached=0;
  796.         }
  797.         else if(strcmp(strtmp,(char *)"TEXTURE:")==0) {
  798.             RetOK=InitTexture(&TmpText,parfile);
  799.         }
  800.         else if(strcmp(strtmp,(char *)"TRANSFORM:")==0) {
  801.             RetOK=InitTransform(&TmpTransform,parfile);
  802.             AddTransform(&TmpText.Transform,&TmpTransform);
  803.         }
  804.         else if(strcmp(strtmp,(char *)":END")==0) {
  805.             EndReached=0;
  806.         }
  807.         else {
  808.             fprintf(stderr,"\nError: Unknown cylinder-keyword \"%s\"\n",strtmp);
  809.             RetOK=-1;
  810.         }
  811.         if((RetOK==0)&&(EndReached!=0)) {
  812.             if(getnextkeyword(parfile,strtmp)!=0) RetOK=-1;        /* Get next keyword */
  813.         }
  814.         }
  815.       }
  816.  
  817.       if(RetOK==0) {
  818.         if((NewObject=(OBJECT *)malloc(sizeof(OBJECT)))!=NULL) {
  819.         if((NewCyl=(CYLINDER *)malloc(sizeof(CYLINDER)))!=NULL) {
  820.             CopyPoint(&NewCyl->Ends[0],&TmpCyl.Ends[0]);
  821.             CopyPoint(&NewCyl->Ends[1],&TmpCyl.Ends[1]);
  822.             CopyPoint(&NewCyl->Discs[1].Centre,&TmpCyl.Ends[1]);
  823.             CopyPoint(&NewCyl->Discs[0].Centre,&TmpCyl.Ends[0]);
  824.             NewCyl->Discs[0].r=TmpCyl.r;
  825.             NewCyl->Discs[1].r=TmpCyl.r;
  826.             CreateVector(&NewCyl->Discs[1].Plane.Normal,TmpCyl.Ends[1].x-TmpCyl.Ends[0].x,TmpCyl.Ends[1].y-TmpCyl.Ends[0].y,TmpCyl.Ends[1].z-TmpCyl.Ends[0].z);
  827.             NegVector(&NewCyl->Discs[0].Plane.Normal,&NewCyl->Discs[1].Plane.Normal);
  828.             nx=NewCyl->Discs[0].Plane.Normal.x*NewCyl->Discs[0].Centre.x;
  829.             ny=NewCyl->Discs[0].Plane.Normal.y*NewCyl->Discs[0].Centre.y;
  830.             nz=NewCyl->Discs[0].Plane.Normal.z*NewCyl->Discs[0].Centre.z;
  831.             NewCyl->Discs[0].Plane.a=nx+ny+nz;    
  832.             nx=NewCyl->Discs[1].Plane.Normal.x*NewCyl->Discs[1].Centre.x;
  833.             ny=NewCyl->Discs[1].Plane.Normal.y*NewCyl->Discs[1].Centre.y;
  834.             nz=NewCyl->Discs[1].Plane.Normal.z*NewCyl->Discs[1].Centre.z;
  835.             NewCyl->Discs[1].Plane.a=nx+ny+nz;    
  836.             NewCyl->r=TmpCyl.r;
  837.  
  838.             NewObject->ShapeType=SHAPE_CYLINDER;
  839.             NewObject->Shape=NewCyl;
  840.             CopyTexture(&NewObject->Texture,&TmpText);
  841.             CopyTransform(&NewObject->Transform,&TmpTransform);
  842.  
  843.             ObjectArray[NumObjects]=NewObject;
  844.             NumObjects++;
  845.         }
  846.         else {
  847.             fprintf(stderr,"\nError: Could not allocate memory for new cylinder\n");
  848.             free(NewObject);
  849.             RetOK=-1;
  850.         }
  851.         }
  852.         else {
  853.         fprintf(stderr,"\nError: Could not allocate memory for new object\n");
  854.         RetOK=-1;
  855.         }
  856.       }
  857.     }
  858.     return(RetOK);
  859. }
  860.  
  861.  
  862.  
  863. int InitNewLight(FILE *parfile)
  864. {
  865.     double    dtmp;
  866.     char    strtmp[100];
  867.     LIGHT    TmpLight, *NewLight;
  868.     int    RetOK=0,EndReached=-1;
  869.  
  870.     fprintf(stderr,".");
  871.  
  872.     if(NumLights>=maxlights) {
  873.         fprintf(stderr,"\n*** Maximum amount of lights exceeded!\n");
  874.         RetOK=-1;
  875.     }
  876.  
  877.     else {
  878.       TmpLight.Location.x=10.0;        /* Set default values */
  879.       TmpLight.Location.y=-10.0;
  880.       TmpLight.Location.z=10.0;
  881.       TmpLight.Color.r=TmpLight.Color.g=TmpLight.Color.b=1.0;
  882.  
  883.       if(getnextkeyword(parfile,strtmp)==0) {        /* Get first keyword */
  884.         while((EndReached!=0)&&(RetOK==0)) {
  885.         if(strcmp(strtmp,(char *)"LOCATION")==0) {
  886.                 if(getnextnumber(parfile,&dtmp)==0)
  887.                 set_dvalue(&TmpLight.Location.x,dtmp,mincoord,maxcoord,strtmp);
  888.                 if(getnextnumber(parfile,&dtmp)==0)
  889.                 set_dvalue(&TmpLight.Location.y,dtmp,mincoord,maxcoord,strtmp);
  890.                 if(getnextnumber(parfile,&dtmp)==0)
  891.                 set_dvalue(&TmpLight.Location.z,dtmp,mincoord,maxcoord,strtmp);
  892.                 else EndReached=0;
  893.         }
  894.         else if(strcmp(strtmp,(char *)"COLOR")==0) {
  895.                 if(getnextnumber(parfile,&dtmp)==0)
  896.                     set_dvalue(&TmpLight.Color.r,dtmp,mincoord,maxcoord,strtmp);
  897.                 if(getnextnumber(parfile,&dtmp)==0)
  898.                     set_dvalue(&TmpLight.Color.g,dtmp,mincoord,maxcoord,strtmp);
  899.                 if(getnextnumber(parfile,&dtmp)==0)
  900.                     set_dvalue(&TmpLight.Color.b,dtmp,mincoord,maxcoord,strtmp);
  901.                 else EndReached=0;
  902.         }
  903.         else if(strcmp(strtmp,(char *)":END")==0) {
  904.             EndReached=0;
  905.         }
  906.         else {
  907.             fprintf(stderr,"\nError: Unknown light-keyword \"%s\"\n",strtmp);
  908.             RetOK=-1;
  909.         }
  910.         if((RetOK==0)&&(EndReached!=0)) {
  911.             if(getnextkeyword(parfile,strtmp)!=0) RetOK=-1;        /* Get next keyword */
  912.         }
  913.         }
  914.       }
  915.  
  916.       if(RetOK==0) {
  917.         if((NewLight=(LIGHT *)malloc(sizeof(LIGHT)))!=NULL) {
  918.         CopyPoint(&NewLight->Location,&TmpLight.Location);
  919.         NewLight->Color.r=TmpLight.Color.r;
  920.         NewLight->Color.g=TmpLight.Color.g;
  921.         NewLight->Color.b=TmpLight.Color.b;
  922.         LightArray[NumLights]=NewLight;
  923.         NumLights++;
  924.         }
  925.         else {
  926.         fprintf(stderr,"\nError: Could not allocate memory for new light\n");
  927.         RetOK=-1;
  928.         }
  929.       }
  930.     }
  931.     return(RetOK);
  932. }
  933.  
  934.  
  935.  
  936.  
  937. int InitCamera(FILE *parfile)
  938. {
  939.     double    dtmp;
  940.     char    strtmp[100];
  941.     int    RetOK=0,EndReached=-1;
  942.  
  943.     fprintf(stderr,".");
  944.  
  945.     if(getnextkeyword(parfile,strtmp)==0) {        /* Get first keyword */
  946.         while((EndReached!=0)&&(RetOK==0)) {
  947.         if(strcmp(strtmp,(char *)"LOCATION")==0) {
  948.                 if(getnextnumber(parfile,&dtmp)==0)
  949.                 set_dvalue(&Camera.Location.x,dtmp,mincoord,maxcoord,strtmp);
  950.                 if(getnextnumber(parfile,&dtmp)==0)
  951.                 set_dvalue(&Camera.Location.y,dtmp,mincoord,maxcoord,strtmp);
  952.                 if(getnextnumber(parfile,&dtmp)==0)
  953.                 set_dvalue(&Camera.Location.z,dtmp,mincoord,maxcoord,strtmp);
  954.                 else EndReached=0;
  955.         }
  956.         else if(strcmp(strtmp,(char *)"VIEWPOINT")==0) {
  957.                 if(getnextnumber(parfile,&dtmp)==0)
  958.                     set_dvalue(&Camera.ViewPoint.x,dtmp,mincoord,maxcoord,strtmp);
  959.                 if(getnextnumber(parfile,&dtmp)==0)
  960.                     set_dvalue(&Camera.ViewPoint.y,dtmp,mincoord,maxcoord,strtmp);
  961.                 if(getnextnumber(parfile,&dtmp)==0)
  962.                     set_dvalue(&Camera.ViewPoint.z,dtmp,mincoord,maxcoord,strtmp);
  963.                 else EndReached=0;
  964.         }
  965.         else if(strcmp(strtmp,(char *)"ASPECT")==0) {
  966.                 if(getnextnumber(parfile,&dtmp)==0)
  967.                     set_dvalue(&Camera.Aspect.x,dtmp,mincoord,maxcoord,strtmp);
  968.                 if(getnextnumber(parfile,&dtmp)==0)
  969.                     set_dvalue(&Camera.Aspect.y,dtmp,mincoord,maxcoord,strtmp);
  970.                 if(getnextnumber(parfile,&dtmp)==0)
  971.                     set_dvalue(&Camera.Aspect.z,dtmp,mincoord,maxcoord,strtmp);
  972.                 else EndReached=0;
  973.         }
  974.         else if(strcmp(strtmp,(char *)":END")==0) {
  975.             EndReached=0;
  976.         }
  977.         else {
  978.             fprintf(stderr,"\nError: Unknown camera-keyword \"%s\"\n",strtmp);
  979.             RetOK=-1;
  980.         }
  981.         if((RetOK==0)&&(EndReached!=0)) {
  982.             if(getnextkeyword(parfile,strtmp)!=0) RetOK=-1;        /* Get next keyword */
  983.         }
  984.         }
  985.     }
  986.     if(RetOK==0)
  987.         CreateCamera(&Camera, &Camera.Location, &Camera.ViewPoint, &Camera.Aspect);
  988.  
  989.     return(RetOK);
  990. }
  991.  
  992.  
  993.  
  994. int InitTexture(TEXTURE *TmpTexture, FILE *parfile)
  995. {
  996.     double    dtmp,d2tmp;
  997.     char    strtmp[100],strtmp2[100];
  998.     int    RetOK=0,EndReached=-1;
  999.     long    lastbound,i;
  1000.  
  1001. /*    fprintf(stderr,"."); */
  1002.  
  1003. /*    CopyTransform(&TmpTexture->Transform,&DefaultTransform); */
  1004.  
  1005.     if(getnextkeyword(parfile,strtmp)==0) {        /* Get first keyword */
  1006.         while((EndReached!=0)&&(RetOK==0)) {
  1007.         if(strcmp(strtmp,(char *)"COLOR")==0) {
  1008.                 if(getnextnumber(parfile,&dtmp)==0) {
  1009.                 set_dvalue(&d2tmp,dtmp,0.0,1.0,strtmp);
  1010.                 TmpTexture->CMap.Colors[0].r=d2tmp;
  1011.             }
  1012.                 if(getnextnumber(parfile,&dtmp)==0) {
  1013.                 set_dvalue(&d2tmp,dtmp,0.0,1.0,strtmp);
  1014.                 TmpTexture->CMap.Colors[0].g=d2tmp;
  1015.             }
  1016.                 if(getnextnumber(parfile,&dtmp)==0) {
  1017.                 set_dvalue(&d2tmp,dtmp,0.0,1.0,strtmp);
  1018.                 TmpTexture->CMap.Colors[0].b=d2tmp;
  1019.             }
  1020.                 else EndReached=0L;
  1021.             TmpTexture->CMap.Colors[1].r=TmpTexture->CMap.Colors[1].g=TmpTexture->CMap.Colors[1].b=0.0;
  1022.             TmpTexture->CMap.Bounds[0]=0.0;
  1023.             TmpTexture->CMap.Bounds[1]=1.0;
  1024.             TmpTexture->CMap.LastBound=1;
  1025.         }
  1026.         else if(strcmp(strtmp,(char *)"COLORMAP")==0) {
  1027.                 if(getnextnumber(parfile,&dtmp)==0)
  1028.             set_ivalue(&lastbound,(long)floor(dtmp),1,10,strtmp);
  1029.             lastbound--;
  1030.             i=0;
  1031.             while((i<=lastbound)&&(EndReached!=0)) {
  1032.                 if(getnextnumber(parfile,&dtmp)==0) {
  1033.                 set_dvalue(&d2tmp,dtmp,0.0,1.0,strtmp);
  1034.                 TmpTexture->CMap.Bounds[i]=d2tmp;
  1035.             }
  1036.                 if(getnextnumber(parfile,&dtmp)==0) {
  1037.                 set_dvalue(&d2tmp,dtmp,0.0,1.0,strtmp);
  1038.                 TmpTexture->CMap.Colors[i].r=d2tmp;
  1039.             }
  1040.                 if(getnextnumber(parfile,&dtmp)==0) {
  1041.                 set_dvalue(&d2tmp,dtmp,0.0,1.0,strtmp);
  1042.                 TmpTexture->CMap.Colors[i].g=d2tmp;
  1043.             }
  1044.                 if(getnextnumber(parfile,&dtmp)==0) {
  1045.                 set_dvalue(&d2tmp,dtmp,0.0,1.0,strtmp);
  1046.                 TmpTexture->CMap.Colors[i].b=d2tmp;
  1047.                 i++;
  1048.             }
  1049.                 else EndReached=0L;
  1050.             }
  1051.             TmpTexture->CMap.LastBound=i;
  1052.         }
  1053.         else if(strcmp(strtmp,(char *)"PATTERN")==0) {
  1054.             if(getnextkeyword(parfile,strtmp2)==0) {
  1055.                 if(strcmp(strtmp2,(char *)"NONE")==0)
  1056.                     TmpTexture->Pattern=PATTERN_NONE;
  1057.                 else if(strcmp(strtmp2,(char *)"CHECKER")==0)
  1058.                     TmpTexture->Pattern=PATTERN_CHECKER;
  1059.                 else if(strcmp(strtmp2,(char *)"CIRCLES")==0)
  1060.                     TmpTexture->Pattern=PATTERN_CIRCLES;
  1061.                 else if(strcmp(strtmp2,(char *)"RINGS")==0)
  1062.                     TmpTexture->Pattern=PATTERN_RINGS;
  1063.                 else if(strcmp(strtmp2,(char *)"SPOTS")==0)
  1064.                     TmpTexture->Pattern=PATTERN_SPOTS;
  1065.                 else if(strcmp(strtmp2,(char *)"GRADIENT")==0)
  1066.                     TmpTexture->Pattern=PATTERN_GRADIENT;
  1067.                 else {
  1068.                     fprintf(stderr,"\nError: Unknown pattern identifier \"%s\"\n",strtmp2);
  1069.                     RetOK=-1;
  1070.                 }
  1071.             }
  1072.                 else EndReached=0;
  1073.         }
  1074.         else if(strcmp(strtmp,(char *)"REFLECT")==0) {
  1075.                 if(getnextnumber(parfile,&dtmp)==0)
  1076.                 set_dvalue(&TmpTexture->Reflect.r,dtmp,0.0,1.0,strtmp);
  1077.                 if(getnextnumber(parfile,&dtmp)==0)
  1078.                 set_dvalue(&TmpTexture->Reflect.g,dtmp,0.0,1.0,strtmp);
  1079.                 if(getnextnumber(parfile,&dtmp)==0)
  1080.                 set_dvalue(&TmpTexture->Reflect.b,dtmp,0.0,1.0,strtmp);
  1081.                 else EndReached=0;
  1082.         }
  1083.         else if(strcmp(strtmp,(char *)"FILTER")==0) {
  1084.                 if(getnextnumber(parfile,&dtmp)==0)
  1085.                 set_dvalue(&TmpTexture->Filter.r,dtmp,0.0,1.0,strtmp);
  1086.                 if(getnextnumber(parfile,&dtmp)==0)
  1087.                 set_dvalue(&TmpTexture->Filter.g,dtmp,0.0,1.0,strtmp);
  1088.                 if(getnextnumber(parfile,&dtmp)==0)
  1089.                 set_dvalue(&TmpTexture->Filter.b,dtmp,0.0,1.0,strtmp);
  1090.                 else EndReached=0;
  1091.         }
  1092.         else if(strcmp(strtmp,(char *)"IOR")==0) {
  1093.                 if(getnextnumber(parfile,&dtmp)==0)
  1094.                 set_dvalue(&TmpTexture->Ior,dtmp,1.0,2.0,strtmp);
  1095.                 else EndReached=0;
  1096.         }
  1097.         else if(strcmp(strtmp,(char *)"AMBIENT")==0) {
  1098.                 if(getnextnumber(parfile,&dtmp)==0)
  1099.                 set_dvalue(&TmpTexture->Ambient,dtmp,0.0,1.0,strtmp);
  1100.                 else EndReached=0;
  1101.         }
  1102.         else if(strcmp(strtmp,(char *)"DIFFUSE")==0) {
  1103.                 if(getnextnumber(parfile,&dtmp)==0)
  1104.                 set_dvalue(&TmpTexture->Diffuse,dtmp,0.0,1.0,strtmp);
  1105.                 else EndReached=0;
  1106.         }
  1107.         else if(strcmp(strtmp,(char *)"PHONG")==0) {
  1108.                 if(getnextnumber(parfile,&dtmp)==0)
  1109.                 set_dvalue(&TmpTexture->Phong,dtmp,0.0,1.0,strtmp);
  1110.                 else EndReached=0;
  1111.         }
  1112.         else if(strcmp(strtmp,(char *)"PHONGSIZE")==0) {
  1113.                 if(getnextnumber(parfile,&dtmp)==0)
  1114.                 set_dvalue(&TmpTexture->PhongSize,dtmp,0.0,100.0,strtmp);
  1115.                 else EndReached=0;
  1116.         }
  1117.         else if(strcmp(strtmp,(char *)"TRANSFORM:")==0) {
  1118.             InitTransform(&TmpTexture->Transform,parfile);
  1119.         }
  1120.         else if(strcmp(strtmp,(char *)"DEFAULT")==0) {
  1121.             CreateDefTexture(TmpTexture);
  1122.         }
  1123.         else if(strcmp(strtmp,(char *)":END")==0) {
  1124.             EndReached=0;
  1125.         }
  1126.         else {
  1127.             fprintf(stderr,"\nError: Unknown texture-keyword \"%s\"\n",strtmp);
  1128.             RetOK=-1;
  1129.         }
  1130.         if((RetOK==0)&&(EndReached!=0)) {
  1131.             if(getnextkeyword(parfile,strtmp)!=0) RetOK=-1;        /* Get next keyword */
  1132.         }
  1133.         }
  1134.     }
  1135.  
  1136.     return(RetOK);
  1137. }
  1138.  
  1139.  
  1140.  
  1141. int InitTransform(TRANSFORM *TmpTransform, FILE *parfile)
  1142. {
  1143.     double    dtmp,d2tmp;
  1144.     char    strtmp[100];
  1145.     int    RetOK=0,EndReached=-1;
  1146.     long    numtransforms;
  1147.  
  1148. /*    fprintf(stderr,"."); */
  1149.  
  1150.     numtransforms=TmpTransform->NumTransforms;
  1151.  
  1152.     if(getnextkeyword(parfile,strtmp)==0) {        /* Get first keyword */
  1153.         while((EndReached!=0)&&(RetOK==0)) {
  1154.         if(numtransforms>=10) {
  1155.             fprintf(stderr,"\n*** Maximum amount of transforms exceeded\n");
  1156.             RetOK=-1;
  1157.         }
  1158.         else if(strcmp(strtmp,(char *)"SCALE")==0) {
  1159.             TmpTransform->Entry[numtransforms].Type=TRANSFORM_SCALE;
  1160.                 if(getnextnumber(parfile,&dtmp)==0) {
  1161.                 set_dvalue(&d2tmp,dtmp,EPSILON,maxcoord,strtmp);
  1162.                 TmpTransform->Entry[numtransforms].Values.x=d2tmp;
  1163.             }
  1164.                 if(getnextnumber(parfile,&dtmp)==0) {
  1165.                 set_dvalue(&d2tmp,dtmp,EPSILON,maxcoord,strtmp);
  1166.                 TmpTransform->Entry[numtransforms].Values.y=d2tmp;
  1167.             }
  1168.                 if(getnextnumber(parfile,&dtmp)==0) {
  1169.                 set_dvalue(&d2tmp,dtmp,EPSILON,maxcoord,strtmp);
  1170.                 TmpTransform->Entry[numtransforms].Values.z=d2tmp;
  1171.             }
  1172.                 else EndReached=0L;
  1173.             if((TmpTransform->Entry[numtransforms].Values.x!=1.0)||(TmpTransform->Entry[numtransforms].Values.y!=1.0)||(TmpTransform->Entry[numtransforms].Values.z!=1.0))
  1174.                 numtransforms++;
  1175.         }
  1176.         else if(strcmp(strtmp,(char *)"MOVE")==0) {
  1177.             TmpTransform->Entry[numtransforms].Type=TRANSFORM_MOVE;
  1178.                 if(getnextnumber(parfile,&dtmp)==0) {
  1179.                 set_dvalue(&d2tmp,dtmp,mincoord,maxcoord,strtmp);
  1180.                 TmpTransform->Entry[numtransforms].Values.x=d2tmp;
  1181.             }
  1182.                 if(getnextnumber(parfile,&dtmp)==0) {
  1183.                 set_dvalue(&d2tmp,dtmp,mincoord,maxcoord,strtmp);
  1184.                 TmpTransform->Entry[numtransforms].Values.y=d2tmp;
  1185.             }
  1186.                 if(getnextnumber(parfile,&dtmp)==0) {
  1187.                 set_dvalue(&d2tmp,dtmp,mincoord,maxcoord,strtmp);
  1188.                 TmpTransform->Entry[numtransforms].Values.z=d2tmp;
  1189.             }
  1190.                 else EndReached=0L;
  1191.             if((TmpTransform->Entry[numtransforms].Values.x!=0.0)||(TmpTransform->Entry[numtransforms].Values.y!=0.0)||(TmpTransform->Entry[numtransforms].Values.z!=0.0))
  1192.                 numtransforms++;
  1193.         }
  1194.         else if(strcmp(strtmp,(char *)"ROTATE")==0) {
  1195.             TmpTransform->Entry[numtransforms].Type=TRANSFORM_ROTATE;
  1196.                 if(getnextnumber(parfile,&dtmp)==0) {
  1197.                 set_dvalue(&d2tmp,dtmp,-99999.0,99999.0,strtmp);
  1198.                 dtmp=fmod(d2tmp,360.0)*RADPDEG;        /* Transform from degrees to radians */
  1199.                 TmpTransform->Entry[numtransforms].Values.x=dtmp;
  1200.             }
  1201.                 if(getnextnumber(parfile,&dtmp)==0) {
  1202.                 set_dvalue(&d2tmp,dtmp,-99999.0,99999.0,strtmp);
  1203.                 dtmp=fmod(d2tmp,360.0)*RADPDEG;
  1204.                 TmpTransform->Entry[numtransforms].Values.y=dtmp;
  1205.             }
  1206.                 if(getnextnumber(parfile,&dtmp)==0) {
  1207.                 set_dvalue(&d2tmp,dtmp,-99999.0,99999.0,strtmp);
  1208.                 dtmp=fmod(d2tmp,360.0)*RADPDEG;
  1209.                 TmpTransform->Entry[numtransforms].Values.z=dtmp;
  1210.             }
  1211.                 else EndReached=0L;
  1212.             if((TmpTransform->Entry[numtransforms].Values.x!=0.0)||(TmpTransform->Entry[numtransforms].Values.y!=0.0)||(TmpTransform->Entry[numtransforms].Values.z!=0.0))
  1213.                 numtransforms++;
  1214.         }
  1215.         else if(strcmp(strtmp,(char *)"NONE")==0) {
  1216.             ClearTransform(TmpTransform);
  1217.         }
  1218.         else if(strcmp(strtmp,(char *)":END")==0) {
  1219.             EndReached=0;
  1220.         }
  1221.         else {
  1222.             fprintf(stderr,"\nError: Unknown transform-keyword \"%s\"\n",strtmp);
  1223.             RetOK=-1;
  1224.         }
  1225.         if((RetOK==0)&&(EndReached!=0)) {
  1226.             if(getnextkeyword(parfile,strtmp)!=0) RetOK=-1;        /* Get next keyword */
  1227.         }
  1228.         }
  1229.         if((RetOK==0)&&(EndReached==0)) {
  1230.         TmpTransform->NumTransforms=numtransforms;
  1231.         }
  1232.     }
  1233.  
  1234.     return(RetOK);
  1235. }
  1236.  
  1237.  
  1238.  
  1239. int InitGlobals(FILE *parfile)
  1240. {
  1241.     double    dtmp;
  1242.     char    strtmp[100];
  1243.     int    RetOK=0,EndReached=-1;
  1244.  
  1245.     fprintf(stderr,".");
  1246.  
  1247.  
  1248.     if(getnextkeyword(parfile,strtmp)==0) {        /* Get first keyword */
  1249.         while((EndReached!=0)&&(RetOK==0)) {
  1250.         if(strcmp(strtmp,(char *)"BACKGROUNDCOLOR")==0) {
  1251.                 if(getnextnumber(parfile,&dtmp)==0)
  1252.                 set_dvalue(&BackgroundColor.r,dtmp,0.0,1.0,strtmp);
  1253.                 if(getnextnumber(parfile,&dtmp)==0)
  1254.                 set_dvalue(&BackgroundColor.g,dtmp,0.0,1.0,strtmp);
  1255.                 if(getnextnumber(parfile,&dtmp)==0)
  1256.                 set_dvalue(&BackgroundColor.b,dtmp,0.0,1.0,strtmp);
  1257.                 else EndReached=0;
  1258.         }
  1259.         else if(strcmp(strtmp,(char *)"RECDEPTH")==0) {
  1260.                 if(getnextnumber(parfile,&dtmp)==0)
  1261.                 set_ivalue(&RecDepth,(long)floor(dtmp),1,50,strtmp);
  1262.                 else EndReached=0;
  1263.         }
  1264.         else if(strcmp(strtmp,(char *)"PICWIDTH")==0) {
  1265.                 if(getnextnumber(parfile,&dtmp)==0)
  1266.                 set_ivalue(&PicWidth,(long)floor(dtmp),1,5000,strtmp);
  1267.                 else EndReached=0;
  1268.         }
  1269.         else if(strcmp(strtmp,(char *)"PICHEIGHT")==0) {
  1270.                 if(getnextnumber(parfile,&dtmp)==0)
  1271.                 set_ivalue(&PicHeight,(long)floor(dtmp),1,5000,strtmp);
  1272.                 else EndReached=0;
  1273.         }
  1274.         else if(strcmp(strtmp,(char *)"ANTIALIASREC")==0) {
  1275.                 if(getnextnumber(parfile,&dtmp)==0)
  1276.                 set_ivalue(&AntiAliasingRec,(long)floor(dtmp),0,3,strtmp);
  1277.                 else EndReached=0;
  1278.         }
  1279.         else if(strcmp(strtmp,(char *)"ANTIALIASTHRESHOLD")==0) {
  1280.                 if(getnextnumber(parfile,&dtmp)==0)
  1281.                 set_dvalue(&AntiAliasingThreshold,dtmp,0.0,3.0,strtmp);
  1282.                 else EndReached=0;
  1283.         }
  1284.         else if(strcmp(strtmp,(char *)"DISPLAY")==0) {
  1285.                 if(getnextnumber(parfile,&dtmp)==0)
  1286.                 set_ivalue(&ReqDisplayType,(long)floor(dtmp),0,9999,strtmp);
  1287.                 else EndReached=0;
  1288.         }
  1289.         else if(strcmp(strtmp,(char *)":END")==0) {
  1290.             EndReached=0;
  1291.         }
  1292.         else {
  1293.             fprintf(stderr,"\nError: Unknown globals keyword \"%s\"\n",strtmp);
  1294.             RetOK=-1;
  1295.         }
  1296.         if((RetOK==0)&&(EndReached!=0)) {
  1297.             if(getnextkeyword(parfile,strtmp)!=0) RetOK=-1;        /* Get next keyword */
  1298.         }
  1299.         }
  1300.     }
  1301.  
  1302.     return(RetOK);
  1303. }
  1304.  
  1305.  
  1306.  
  1307. /*****************************************************************
  1308.  *
  1309.  *      Setup default globals
  1310.  *
  1311.  *****************************************************************/
  1312.  
  1313. void SetupDefaults(void)
  1314. {
  1315.     RecDepth=3;
  1316.     PicWidth=200; PicHeight=150;
  1317.     BackgroundColor.r=0.0; BackgroundColor.g=0.0; BackgroundColor.b=0.0;
  1318.     AntiAliasingRec=0L; AntiAliasingThreshold=0.3; AntiAliasingJitter=0.05; 
  1319.     ReqDisplayType=0L;
  1320.     
  1321.     Camera.Location.x=0.0; Camera.Location.y=-10.0; Camera.Location.z=1.0;
  1322.     Camera.ViewPoint.x=0.0; Camera.ViewPoint.y=0.0; Camera.ViewPoint.z=0.0; 
  1323.     Camera.Aspect.x=4.0; Camera.Aspect.y=3.0; Camera.Aspect.z=5.0;
  1324.     CreateCamera(&Camera, &Camera.Location, &Camera.ViewPoint, &Camera.Aspect);
  1325.  
  1326.     CreateDefTexture(&DefaultTexture);
  1327.     ClearTransform(&DefaultTransform);
  1328. }
  1329.  
  1330.  
  1331.  
  1332. /*****************************************************************
  1333.  *
  1334.  *      Miscellanous subroutines
  1335.  *
  1336.  *****************************************************************/
  1337.  
  1338.  
  1339. /*
  1340.  *                          ----------
  1341.  *                         *-- NOTE --*
  1342.  *                          ----------
  1343.  *
  1344.  * These routines may have to be changed if your system uses a
  1345.  * non-ascii standard. Sorry about that, but I guess most systems
  1346.  * ARE ascii today...
  1347.  *
  1348.  */
  1349.  
  1350.  
  1351. int ischar(int a)
  1352. {
  1353.     int    b;
  1354.  
  1355.     b=-1;
  1356.     if((a>=33)&&(a<=126)) b=0;        /* chr(a) = "!..~" (all chars) */
  1357.     return(b);
  1358. }
  1359.  
  1360. int isletter(int *a)
  1361. {
  1362.     int    b;
  1363.  
  1364.     b=-1;
  1365.     if((*a>=(int)'a')&&(*a<=(int)'z')) *a=*a-(int)'a'+(int)'A';    /* Make uppercase */
  1366.     if(((*a>=(int)'A')&&(*a<=(int)'Z'))||(*a==(int)':')) b=0;    /* chr(a) = "A..Z" or ":" */
  1367.  
  1368.     return(b);
  1369. }
  1370.  
  1371. int isnumber(int a)
  1372. {
  1373.     int    b;
  1374.  
  1375.     b=-1;
  1376.     if(((a>=(int)'0')&&(a<=(int)'9'))||(a==(int)'-')||(a==(int)'.')) b=0;    /* chr(a) = "0..9" or "-" or "." */
  1377.     return(b);
  1378. }
  1379.  
  1380. int iscomment(int a)
  1381. {
  1382.     int    b;
  1383.  
  1384.     b=-1;
  1385.     if((a==(int)'#')||(a==(int)';')||(a==(int)'*')) b=0;
  1386.     return(b);
  1387. }
  1388.  
  1389.  
  1390. int isnewline(int a)
  1391. {
  1392.     int    b;
  1393.  
  1394.     b=-1;
  1395.     if((a==(int)10)||(a==(int)13)) b=0;
  1396.     return(b);
  1397. }
  1398.  
  1399.  
  1400. int getnextkeyword(FILE *f, char *keyword)
  1401. {
  1402.     int    itmp,i;
  1403.  
  1404.     i=0;
  1405.     keyword[0]=(char) 0;
  1406.     itmp=fgetc(f);
  1407.     while((itmp!=EOF)&&(isletter(&itmp)!=0)) {
  1408.         if(iscomment(itmp)==0) {
  1409.             while((itmp!=EOF)&&(isnewline(itmp)!=0)) {
  1410.             itmp=fgetc(f);
  1411.             }
  1412.         }
  1413.         itmp=fgetc(f);
  1414.     }
  1415.     while((itmp!=EOF)&&(isletter(&itmp)==0)&(i<99)) {
  1416.         keyword[i]=(char)itmp;
  1417.         itmp=fgetc(f);
  1418.         i++;
  1419.     }
  1420.     if(itmp==EOF) { return(-1); }
  1421.     else{
  1422.         keyword[i]=(char)0;
  1423.         return(0);
  1424.     }
  1425. }
  1426.  
  1427. int getnextnumber(FILE *f, double *number)
  1428. {
  1429.     int    itmp,i;
  1430.     char    string[100];
  1431.  
  1432.     i=0;
  1433.     string[0]=(char)"0"; string[1]=(char)0;
  1434.     itmp=fgetc(f);
  1435.     while((itmp!=EOF)&&(isnumber(itmp)!=0)) {
  1436.         if(iscomment(itmp)==0) {
  1437.             while((itmp!=EOF)&&(isnewline(itmp)!=0)) {
  1438.             itmp=fgetc(f);
  1439.             }
  1440.         }
  1441.         itmp=fgetc(f);
  1442.     }
  1443.     while((itmp!=EOF)&&(isnumber(itmp)==0)&&(i<99)) {
  1444.         string[i]=(char)itmp;
  1445.         itmp=fgetc(f);
  1446.         i++;
  1447.     }
  1448.     if(itmp==EOF) { return(-1); }
  1449.     else{
  1450.         string[i]=(char)0;
  1451.         *number=atof(string);
  1452.         return(0);
  1453.     }
  1454. }
  1455.  
  1456. void set_ivalue(long *variable, long value, long min, long max, char *string)
  1457. {
  1458.     if((value>=min)&&(value<=max)) *variable=value;
  1459.     else {
  1460.         fprintf(stderr,"\n   Warning: Invalid value for %s: %ld\n",string,value);
  1461.         if(value>max) *variable=max;
  1462.         if(value<min) *variable=min;
  1463.         fprintf(stderr,"            Set to: %ld\n",*variable);
  1464.     }
  1465. }
  1466.  
  1467. void set_dvalue(double *variable, double value, double min, double max, char *string)
  1468. {
  1469.     if((value>=min)&&(value<=max)) *variable=value;
  1470.     else {
  1471.         fprintf(stderr,"\n   Warning: Invalid value for %s: %lf\n",string,value);
  1472.         if(value>max) *variable=max;
  1473.         if(value<min) *variable=min;
  1474.         fprintf(stderr,"            Set to: %lf\n",*variable);
  1475.     }
  1476. }
  1477.  
  1478.